package org.l.mybatis.core.sqlsource;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMapping.Builder;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.l.mybatis.core.exception.MethodDefineException;
import org.l.mybatis.core.handler.FieldHandler;
import org.l.mybatis.core.handler.ObjectHandler;

/**
 * Created by 严秋旺 on 2017/7/30.
 */
public abstract class SqlsourceBuilderAbstract {
    protected Configuration configuration;
    protected Class<?> type;
    protected Method method;
    protected int paramCount = 0;
    protected Map<String, Object> params = new HashMap<>();

    public SqlsourceBuilderAbstract(Configuration configuration, Class<?> type, Method method)
            throws MethodDefineException {
        this.configuration = configuration;
        this.type = type;
        this.method = method;
    }

    /**
     * 创建where子句
     * @param paramPrefix
     * @param parameterMappings
     * @param metaObject
     * @param fields
     * @return
     */
    protected String createWhere(String paramPrefix, List<ParameterMapping> parameterMappings, MetaObject metaObject,
            List<FieldHandler> fields) {
        StringBuilder where = new StringBuilder();
        int i = -1;

        for (FieldHandler handler : fields) {
            i++;
            Object value = metaObject.getValue(handler.getName());

            if (value == null)
                continue;

            if (i > 0)
                where.append(" and ");

            where.append(handler.getDbName()).append(" = ?");
            parameterMappings.add(createParameterMapping(handler, paramPrefix));
        }

        if (where.length() > 0) {
            where.insert(0, " where ");
        }

        return where.toString();
    }

    /**
     * 创建ps参数
     * @param fieldHandler
     * @return
     */
    protected ParameterMapping createParameterMapping(FieldHandler fieldHandler) {
        return createParameterMapping(fieldHandler, null);
    }

    /**
     * 创建ps参数
     * @param fieldHandler
     * @param paramPrefix
     * @return
     */
    protected ParameterMapping createParameterMapping(FieldHandler fieldHandler, String paramPrefix) {
        String property;

        if (StringUtils.isEmpty(paramPrefix)) {
            property = fieldHandler.getName();
        } else {
            property = paramPrefix + '.' + fieldHandler.getName();
        }

        ParameterMapping.Builder builder = new Builder(configuration, property, fieldHandler.getType());
        builder.jdbcType(fieldHandler.getJdbcType());
        return builder.build();
    }

    /**
     * 根据指定字段获取实体属性FieldHandler列表
     * @param objectHandler
     * @param fields
     * @return
     */
    protected List<FieldHandler> fieldHandles(ObjectHandler objectHandler, String[] fields) {
        List<FieldHandler> fieldHandlers = new ArrayList<>();

        for (String field : fields) {
            FieldHandler handler = objectHandler.getFieldHandlerByDbField(field);
            fieldHandlers.add(handler);
        }
        
        return fieldHandlers;
    }
}
